/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2010 huliqing, huliqing.cn@gmail.com
 *
 * This file is part of QFaces.
 * QFaces is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * QFaces is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with QFaces.  If not, see <http://www.gnu.org/licenses/>.
 *
 * 这个文件是QFaces的一部分。
 * 您可以单独使用或分发这个文件，但请不要移除这个头部声明信息.
 * QFaces是一个自由软件，您可以自由分发、修改其中的源代码或者重新发布它，
 * 新的任何修改后的重新发布版必须同样在遵守LGPL3或更后续的版本协议下发布.
 * 关于LGPL协议的细则请参考COPYING、COPYING.LESSER文件，
 * 您可以在QFaces的相关目录中获得LGPL协议的副本，
 * 如果没有找到，请连接到 http://www.gnu.org/licenses/ 查看并获取副本。
 *
 * - Author: Huliqing
 * - Contact: huliqing.cn@gmail.com
 * - License: GNU Lesser General Public License (LGPL)
 * - Blog and source code availability: http://www.huliqing.name/
 */


package name.huliqing.qfaces;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.FacesException;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author huliqing
 */
public final class HttpWriter {

    private final static Logger logger = Logger.getLogger(HttpWriter.class.getName());
    private FacesContext fc;

    public HttpWriter(FacesContext fc) {
        this.fc = fc;
    }

    public void writeCSS(String path)
            throws FacesException {
        if (!checkPath(path)) {
            return;
        }
        if (!path.contains("/")) {
            path = Constant.QFACES_DIR_RESOURCE + path;
        }
        HttpServletResponse response = (HttpServletResponse) fc.getExternalContext().getResponse();
        response.setContentType("text/css");
        response.setCharacterEncoding("utf-8");
        try {
            writeResource(response, path);
        } catch (IOException ioe) {
            logger.severe("Couldn't load css. Make sure your file"
                    + "path like this \"name/huliqing/qfaces/resource/mystyle.css\","
                    + "and not start width \"/\"");
            logger.log(Level.SEVERE, ioe.getMessage(), ioe);
        }
    }

    public void writeScript(String path)
            throws FacesException {
        if (!checkPath(path)) {
            return;
        }
        if (!path.contains("/")) {
            path = Constant.QFACES_DIR_RESOURCE + path;
        }
        HttpServletResponse response = (HttpServletResponse) fc.getExternalContext().getResponse();
        response.setContentType("text/javascript");
        response.setCharacterEncoding("utf-8");

        try {
            writeResource(response, path);
        } catch (IOException ioe) {
            logger.severe("Couldn't load javascript. Make sure your file"
                    + "path like this \"name/huliqing/qfaces/resource/somejs.js\","
                    + "and not start width \"/\"");
            logger.log(Level.SEVERE, ioe.getMessage(), ioe);
        }
    }

    public void writeImg(String path) throws FacesException {
        if (!checkPath(path)) {
            return;
        }
        if (!path.contains("/")) {
            path = Constant.QFACES_DIR_IMAGE + path;
        }
        HttpServletResponse response = (HttpServletResponse) fc.getExternalContext().getResponse();
        response.setContentType("image/jpeg");
        try {
            writeResource(response, path);
        } catch (IOException ioe) {
            logger.severe("Couldn't load images.Make sure this file"
                    + "path like this \"name/huliqing/qfaces/resource/someimage.png\","
                    + "and not start width \"/\"");
            logger.log(Level.SEVERE, ioe.getMessage(), ioe);
        }
    }

    // 检查并验证path是否存在安全问题,只允许输出js,css,gif,jpg,png文件类型。
    private boolean checkPath(String path) {
        if (path == null || "".equals(path)) {
            return false;
        }
        String _path = path.toLowerCase();
        if (_path.endsWith(".js")
                || _path.endsWith(".css")
                || _path.endsWith(".gif")
                || _path.endsWith(".jpg")
                || _path.endsWith(".png")) {
            return true;
        } else {
            logger.severe("Forbidden, 不支持除以下类型外的资源输出:js, css, gif, jpg, png, 目标=" + path);
            return false;
        }
    }

    private void writeResource(HttpServletResponse response, String path) throws IOException {
        boolean develop = Boolean.parseBoolean(fc.getExternalContext().getInitParameter("name.huliqing.qfaces.DEVELOP"));
        // Cache-Control :private、no-cache、max-age、must-revalidate
        if (develop) {
            response.setHeader("Cache-Control", "no-cache");
        } else {
            response.setHeader("Cache-Control", "max-age=" + (3600 * 24 * 7)); // 7 Days to cache
        }
        OutputStream out = response.getOutputStream();
        InputStream in = getClass().getClassLoader().getResourceAsStream(path);
        byte[] buff = new byte[10240];
        int len;
        while ((len = in.read(buff)) != -1) {
            out.write(buff, 0, len);
        }
        out.close();
        in.close();
    }
}
